/*************************************************************************
 * Copyright(C),2017,ZDC Corporation.
 * All right reserved.
 * 
 * File Name: server.c
 * Description:
 * Author: madechuan
 * Mail: mdc@zcom.nj
 * Created Time: 2017年11月02日 星期四 23时45分32秒
 ************************************************************************/
#include "catch.h"
unsigned long kernel(unsigned char *packet);
/*********************服务端接收函数(tcp)*********************/
void tcpserver(void)
{
    int tlistenfd;   //监听套接字
    int tconnfd;    //连接后的套接字
    unsigned char packet[128];
    struct sockaddr_in servaddr,cliaddr;
    socklen_t peerlen;
    char ttransbuf[128];//tcp传输用的buf
    //建立socket连接
    if (-1 == (tlistenfd = socket(AF_INET,SOCK_STREAM,0)))
    {
        perror("socket");
        exit(-1);
    }
   // printf("tlistenfd is %d\n",tlistenfd);
    //设置sockaddr_in结构体中相关的参数
    bzero(&servaddr,sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(atoi("8888"));
    servaddr.sin_addr.s_addr = INADDR_ANY;
    //绑定函数
    if (bind(tlistenfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) < 0)
    {
        perror("bind");
        exit(-1);
    }

    printf(" [ tcp bind success ]\n");
    //调用listen函数，设置监听模式
    if (-1 == listen(tlistenfd,10))
    {
        perror("listen");
        exit(-1);
    }
    printf(" [ listening...     ]\n");
    //调用accept函数，等待客户端的连接
    peerlen = sizeof(cliaddr);
    while(1)
    {
        printf(" [ waiting to accept ]\n");
        if ((tconnfd = accept(tlistenfd,(struct sockaddr *)&cliaddr,&peerlen)) < 0)
        {
            perror("accept");
            exit(-1);
        }
        printf(" [ 客户端已连接 ]\n");
        //调用recv函数接收发送端发来的数据
        if (-1 == recv(tconnfd,packet,128,0))
        {
            perror("recv");
            exit(-1);
        }
        int recvflag = 1;//服务端接收到报文标志位 
        send(tconnfd,&recvflag,5,0);//发送标志位给客户端响应
        memset(&recvflag,0,4);

        unsigned long systick;//用来存放系统滴答
        systick = kernel(packet);//调用内核读写函数
        recvflag = 0;//响应完成后将标志位置为0
        send(tconnfd,&systick,128,0);//将内核中的系统滴答发送给客户端
        if (-1 == recv(tconnfd,&recvflag,5,0))
        {
            perror("recv");
            exit(-1);
        }
        if (1 == recvflag)
        {
            printf(" [ 客户端已收到滴答信息（客户端响应）]\n");
        }
        else
        {
            printf(" [ 客户端没有收到报文信息（客户端响应）]\n");
        }

        close(tconnfd);
        //break;
    }
    close(tlistenfd);

}
/****************内核读写**************/
unsigned long kernel(unsigned char *packet)
{
    int fd;
    unsigned long tickbuf[128];
    int len;


    fd = open("/dev/server",O_RDWR);
    if(fd<0)
    {
        perror("open fail\n");
        return 0;
    }

    write(fd,packet,128);//将server收到的buf写入内核的kbuf中并打印

    len = read(fd,tickbuf,127);
    //tickbuf[len]='\0';
    printf("  从内核读出的系统滴答:%lu\n",tickbuf[0]);

    close(fd);	
    return tickbuf[0];
}
int main(int argc, char *argv[])
{
    tcpserver() ;
    return 0;
}
